/*
 * Copyright 2003-2005 (c) Live Media Pty Ltd. <argot@einet.com.au> 
 *
 * This software is licensed under the Argot Public License 
 * which may be found in the file LICENSE distributed 
 * with this software.
 *
 * More information about this license can be found at
 * http://www.einet.com.au/License
 * 
 * The Developer of this software is Live Media Pty Ltd,
 * PO Box 4591, Melbourne 3001, Australia.  The license is subject 
 * to the law of Victoria, Australia, and subject to exclusive 
 * jurisdiction of the Victorian courts.
 */

#ifndef TYPEMAP
#define TYPEMAP

#ifdef __cplusplus
extern "C" {
#endif


struct type_map_vtable
{
    int (*map)( type_map * map, int id, int systemid );
    int   (*get_id)( type_map * map, type_name * name );
	type_name * (*get_name)( type_map * map, int id );
    typeReader (*get_reader)( type_map * map, int id );
    typeWriter (*get_writer)( type_map * map, int id );
    type_element * (*get_structure)( type_map * map, int id );
    int (*get_library_id)( type_map * map, int id );
    int (*get_mapped_id)( type_map * map, int systemId );
    bool (*is_valid_id)( type_map * map, int id );
    bool (*is_valid_name)( type_map * map, type_name * name );
    int (*get_size)( type_map * map );
}; 

struct type_map
{
	struct type_map_vtable * __vt;
	type_library * library;
	intmap map;
};

#define TYPE_NOT_MAPPED -2

void type_map_init( type_map * map, type_library * library );
type_map * type_map_create( type_library * library );
void type_map_destroy( type_map * map );

#define type_map_get_library( map ) ((map)->library)

#define type_map_map( m, id, systemid ) (*(((type_map*)(m))->__vt->map))( ((type_map*)(m)), (id), (systemid) )
#define type_map_get_id( map, name ) (*(((type_map*)(map))->__vt->get_id))( ((type_map*)(map)), (name) )
#define type_map_get_name(map, id ) (*(((type_map*)(map))->__vt->get_name))( ((type_map*)(map)), (id) )
#define type_map_get_reader( map, id ) (*(((type_map*)(map))->__vt->get_reader))( ((type_map*)(map)), (id) )
#define type_map_get_writer( map, id ) (*(((type_map*)(map))->__vt->get_writer))( ((type_map*)(map)), (id) )
#define type_map_get_structure( map, id ) (*(((type_map*)(map))->__vt->get_structure))( ((type_map*)(map)), (id) )
#define type_map_get_library_id( map, id ) (*(((type_map*)(map))->__vt->get_library_id))( ((type_map*)(map)), (id) )
#define type_map_get_mapped_id( map, systemId ) (*(((type_map*)(map))->__vt->get_mapped_id))( ((type_map*)(map)), (systemId) )
#define type_map_is_valid_id( map, id ) (*(((type_map*)(map))->__vt->is_valid_id))( ((type_map*)(map)), (id) )
#define type_map_is_valid_name( map, name ) (*(((type_map*)(map))->__vt->is_valid_name))( ((type_map*)(map)), (name) )
#define type_map_get_size( map ) (*(((type_map*)(map))->__vt->get_size))( ((type_map*)(map)) )

typedef struct type_map_iterator
{
	intmap_iterator iter;
}
type_map_iterator;

void type_map_iterator_init( type_map_iterator * iter, type_map * map );
bool type_map_iterator_next( type_map_iterator * iter );
int type_map_iterator_id( type_map_iterator * iter );

/* Base functions.  Do not call directly unless overloading functions */
int _type_map_map( type_map * map, int id, int systemid );
int _type_map_get_id( type_map * map, type_name * name );
type_name * _type_map_get_name( type_map * map, int id );
typeReader _type_map_get_reader( type_map * map, int id );
typeWriter _type_map_get_writer( type_map * map, int id );
type_element * _type_map_get_structure( type_map * map, int id );
int _type_map_get_library_id( type_map * map, int id );
int _type_map_get_mapped_id( type_map * map, int systemId );
bool _type_map_is_valid_id( type_map * map, int id );
bool _type_map_is_valid_name( type_map * map, type_name * name );
int _type_map_get_size( type_map * map );


#ifdef __cplusplus
}
#endif

#endif
